package beautiful.butterfly.drds.binlog.connection;

import beautiful.butterfly.drds.binlog.netty.server.NioSocketChannelExtend;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class ConnectionFactory
{

    private static ConcurrentHashMap<String, NioSocketChannelExtend> ipAndPortToNioSocketChannelExtendMap = new ConcurrentHashMap<String, NioSocketChannelExtend>();

    public static void put(String ipAndPort, NioSocketChannelExtend nioSocketChannelExtend)
    {
        ipAndPortToNioSocketChannelExtendMap.put(ipAndPort, nioSocketChannelExtend);
    }

    public static NioSocketChannelExtend get(String ipAndPort)
    {
        return ipAndPortToNioSocketChannelExtendMap.get(ipAndPort);
    }

    public static NioSocketChannelExtend remove(String ipAndPort)
    {
        return ipAndPortToNioSocketChannelExtendMap.remove(ipAndPort);
    }

    //
    private static SocketChannelAndIp newSocketChannelAndIp(String ipsString, int port)
    {
        // 因为可能是多个ip
        SocketChannelAndIp socketChannelAndIp = null;
        String[] ips = ipsString.split(",");
        for (String ip : ips)
        {
            try
            {
                socketChannelAndIp = new SocketChannelAndIp(SocketChannel.open(new InetSocketAddress(ip, port)), ip);
                socketChannelAndIp.getSocketChannel().socket().setKeepAlive(true);
                break;
            } catch (IOException e)
            {
                socketChannelAndIp = null;
                log.info("fail to connect " + ip + ":" + port);
            }
        }
        return socketChannelAndIp;
    }

    public static Connection makeObject(
            String ips, //
            int port,//
            String data,//
            String runningPath,//
            String binlogPositionPath,//
            String initialFilename,//
            long initialPosition,//
            long clientId)//
    {
        Connection connection = null;
        if (null != ips && port >= 0)
        {
            try
            {
                // 在这里创建具体的对象
                SocketChannelAndIp socketChannelAndIp = newSocketChannelAndIp(ips, port);
                if (null == socketChannelAndIp)
                {
                    throw new Exception("connect all target machines ,fail!!!");
                }
                socketChannelAndIp.getSocketChannel().configureBlocking(false);// 非阻塞
                connection = new Connection(socketChannelAndIp.getSocketChannel(),
                        ConnectionAttributes.parse(data).setIpPort(ips, port, socketChannelAndIp.getIp())
                                .setRunningPath(runningPath).setBinlogPositionPath(binlogPositionPath)
                                .setClientId(clientId).updateBinlogFileNameAndPosition(initialFilename, initialPosition));
            } catch (Exception e)
            {
                connection = null;
                log.info(e.toString());
            }
        }
        // 无论如何，都返回连接，失敗則返回null
        return connection;
    }

}
